<script setup>
// 文档、富文本组件
import {
  ref,
  watch,
  onBeforeUnmount,
  shallowRef,
  nextTick,
  computed,
  reactive,
} from 'vue'
import { debounce } from '@/utils/tools.ts'
import '@wangeditor/editor/dist/css/style.css'
import { Toolbar, Editor } from '@wangeditor/editor-for-vue'
import { SlateEditor, SlateElement, SlateTransforms } from '@wangeditor/editor'
import {
  ToolbarConfigs,
  uploadImageConfig,
} from './documentTools/toolbar-config.js'
import formulaModule from '@wangeditor/plugin-formula'
import { Boot } from '@wangeditor/editor'

const props = defineProps({
  content: {
    type: String,
    default: '',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
})
const editorRef = shallowRef()
const contentHtml = ref('')
const emits = defineEmits(['onSave'])
const soLink = ref(false)

onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

const handleCreated = (editor) => {
  editorRef.value = editor
  if (!editor.getAllMenuKeys()?.includes('insertFormula')) {
    Boot.registerModule(formulaModule)
  }
  nextTick(() => {
    contentHtml.value = props.content
    if (props.disabled) {
      props.disabled && editorRef.value && editorRef.value.disable()
      return
    }
    nextTick(async () => {
      await editorRef.value.focus()
      // editorRef.value.insertNode({ text: '' })
    })
  })
}

const handleDestroyed = () => {
  editorRef.value = false
}

const saveContent = (value) => {
  emits('onSave', value)
}

const configLink = computed(() => {
  if (!soLink.value) {
    return ['editLink', 'unLink', 'viewLink']
  } else {
    return ['viewLink']
  }
})

const editorConfig = reactive({
  placeholder: '请输入内容...',
  hoverbarKeys: {
    formula: {
      menuKeys: ['editFormula'],
    },
    link: {
      menuKeys: configLink,
    },
  },
  MENU_CONF: { uploadImage: uploadImageConfig },
})

watch(
  () => props.content,
  (value) => {
    if (value !== contentHtml.value) {
      contentHtml.value = value
    }
  },
)
const changeAction = debounce(() => {
  let flag = props.content !== contentHtml.value
  if (flag) {
    saveContent(contentHtml.value)
  }
}, 800)

const handleChange = (editor) => {
  const nodeEntries = SlateEditor.nodes(editor, {
    match: (node) => {
      if (SlateElement.isElement(node)) {
        const { type } = node
        return type === 'link'
      }
      return false
    },
    universal: true,
  })
  let shoLink = false
  if (nodeEntries !== null) {
    for (let nodeEntry of nodeEntries) {
      const [node] = nodeEntry
      const { type, url } = node
      if (
        type === 'link' &&
        (url.indexOf('file/doc') > 0 ||
          url.indexOf('file/mindmap') > 0 ||
          url.indexOf('file/drawio') > 0)
      ) {
        shoLink = true
        if (
          props.content !== contentHtml.value &&
          props.content.length > contentHtml.value.length
        ) {
          SlateTransforms.removeNodes(editor, {
            match: (no) => {
              if (SlateElement.isElement(no)) {
                return no.type === 'link'
              }
              return false
            },
          })
        }
      }
    }
    soLink.value = shoLink
  }
  changeAction()
}

const heightTools = ref(0)
const handler = (value) => {
  heightTools.value = value.height
}
</script>

<template>
  <div class="" style="height: 100%; min-height: 700px" id="">
    <Toolbar
      v-resize="handler"
      class="document-toolbar"
      :editor="editorRef"
      :default-config="{ toolbarKeys: ToolbarConfigs }"
      mode="default"
    />
    <Editor
      :defaultConfig="editorConfig"
      mode="default"
      v-model="contentHtml"
      @onCreated="handleCreated"
      @onDestroyed="handleDestroyed"
      @onChange="handleChange"
      :style="{
        height: `calc(100% - ${heightTools}px)`,
        minHeight: '500px',
      }"
      class="editor-container"
    />
  </div>
</template>

<style scoped lang="scss">
.editor-container {
  min-height: 500px;
}
// .document-container {
//   border: var(--el-border);
//   min-width: 800px;

//   .document-toolbar {
//     border-bottom: var(--el-border);
//   }
// }
</style>
